package com.xique.blelock.view.DeviceManager;

import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothGatt;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.InputType;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.Menu;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.MaterialDialog;
import com.alibaba.fastjson.JSON;
import com.clj.fastble.BleManager;
import com.clj.fastble.callback.BleGattCallback;
import com.clj.fastble.callback.BleScanAndConnectCallback;
import com.clj.fastble.callback.BleScanCallback;
import com.clj.fastble.data.BleDevice;
import com.clj.fastble.exception.BleException;
import com.clj.fastble.scan.BleScanRuleConfig;
import com.clj.fastble.utils.HexUtil;
import com.ivin.crop.Log;
import com.qmuiteam.qmui.widget.QMUIFloatLayout;
import com.qmuiteam.qmui.widget.dialog.QMUIBottomSheet;
import com.qmuiteam.qmui.widget.grouplist.QMUIGroupListView;
import com.xique.MyApplication;
import com.xique.blelock.Adapter.DeviceAdapter;
import com.xique.blelock.Interface.BleConnectListen;
import com.xique.blelock.Interface.BleListenData;
import com.xique.blelock.Interface.BleNotificationListen;
import com.xique.blelock.Interface.OnItemClickListener;
import com.xique.blelock.NetUtils.NetResult;
import com.xique.blelock.NetUtils.XqNetClient;
import com.xique.blelock.R;
import com.xique.blelock.Utils.BleUtils;
import com.xique.blelock.Utils.Stringkey;
import com.xique.blelock.Utils.TimeUtil;
import com.xique.blelock.model.LockInfo;
import com.xique.blelock.view.AcountManager.FingerListActivty;
import com.xique.blelock.view.BaseActivity;
import com.xique.blelock.view.Home_Activity;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

import static com.xique.blelock.Utils.Stringkey.firmwareverindex;
import static com.xique.blelock.Utils.Stringkey.hardverindex;
import static com.xique.blelock.Utils.Stringkey.lockstatusindex;
import static com.xique.blelock.Utils.Stringkey.serialindex;
import static com.xique.blelock.Utils.Stringkey.vendorindex;
import static com.xique.blelock.Utils.Stringkey.volumindex;


public class Adddevice_Activity extends BaseActivity implements  BleListenData, BleConnectListen, BleNotificationListen {
    private final static String TAG = Adddevice_Activity.class.getSimpleName();
    private static final int REQUEST_CODE_OPEN_GPS = 1;
    private static final int REQUEST_CODE_PERMISSION_LOCATION = 2;

    private LinearLayout BACKTEM,Searchble,chongxinble;
    private ImageView xiansiview;
    private TextView zghanwushebei,Mgoadd;
    private Button chongxin;


    //扫描出来的设备列表布局layout
    @BindView(R.id.groupListView)
    RecyclerView recyclerView;

    @BindView(R.id.title)
    TextView title;




    //Searchble  正在搜索设备
    //chongxinble 没有搜索到设备界面
    @BindView(R.id.devicelayout)
    View devicelayout;

    private List<BleDevice> bleDevices = new ArrayList<>();

    private QMUIBottomSheet qmuiBottomSheet;

    DeviceAdapter deviceAdapter;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.adddeviceactivity );
        ButterKnife.bind(this);
        initview();

        //初始化蓝牙 设备
        initBle();
        checkPermissions();


    }


    private void startScan() {
        setScanRule();
        BleManager.getInstance().scan(scanCallback);
    }

    //蓝牙扫描回调接口
    private BleScanCallback scanCallback =  new BleScanCallback() {
        @Override
        public void onScanStarted(boolean success) {
            // 开始扫描的回调
        }

        @Override
        public void onScanning(BleDevice bleDevice) {
            // 扫描到一个之前没有扫到过的设备的回调
            Log.e("扫描到一个设备  mac="+ bleDevice.getMac() + " name="+bleDevice.getName()+ "  data"+ new String(bleDevice.getScanRecord()), "");

//            if(BleUtils.cotainUUID(bleDevice, Stringkey.SERVICE_UUID)){
                bleDevices.add(bleDevice);
                startshowDevice();
//            }


        }

        @Override
        public void onScanFinished(List<BleDevice> scanResultList) {
            // 扫描完成的回调，列表里将不会有重复的设备

            stopScanBle();


        }
    };

    @Override
    public final void onRequestPermissionsResult(int requestCode,
                                                 @NonNull String[] permissions,
                                                 @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case REQUEST_CODE_PERMISSION_LOCATION:
                if (grantResults.length > 0) {
                    for (int i = 0; i < grantResults.length; i++) {
                        if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
                            onPermissionGranted(permissions[i]);
                        }
                    }
                }
                break;
        }
    }


    private void checkPermissions() {
        BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (!bluetoothAdapter.isEnabled()) {
            //Toast.makeText(this, getString(R.string.please_open_blue), Toast.LENGTH_LONG).show();
            return;
        }

        String[] permissions = {Manifest.permission.ACCESS_FINE_LOCATION};
        List<String> permissionDeniedList = new ArrayList<>();
        for (String permission : permissions) {
            int permissionCheck = ContextCompat.checkSelfPermission(this, permission);
            if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
                onPermissionGranted(permission);
            } else {
                permissionDeniedList.add(permission);
            }
        }
        if (!permissionDeniedList.isEmpty()) {
            String[] deniedPermissions = permissionDeniedList.toArray(new String[permissionDeniedList.size()]);
            ActivityCompat.requestPermissions(this, deniedPermissions, REQUEST_CODE_PERMISSION_LOCATION);
        }
    }
    private void onPermissionGranted(String permission) {
        switch (permission) {
            case Manifest.permission.ACCESS_FINE_LOCATION:
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !checkGPSIsOpen()) {
                    new AlertDialog.Builder(this)
                            .setTitle(R.string.notifyTitle)
                            .setMessage(R.string.gpsNotifyMsg)
                            .setNegativeButton(R.string.cancel,
                                    new DialogInterface.OnClickListener() {
                                        @Override
                                        public void onClick(DialogInterface dialog, int which) {
                                            finish();
                                        }
                                    })
                            .setPositiveButton(R.string.setting,
                                    new DialogInterface.OnClickListener() {
                                        @Override
                                        public void onClick(DialogInterface dialog, int which) {
                                            Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                                            startActivityForResult(intent, REQUEST_CODE_OPEN_GPS);
                                        }
                                    })

                            .setCancelable(false)
                            .show();
                } else {
//                    setScanRule();
                    startScan();

                }
                break;
        }
    }
    private boolean checkGPSIsOpen() {
        LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
        if (locationManager == null)
            return false;
        return locationManager.isProviderEnabled(android.location.LocationManager.GPS_PROVIDER);
    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE_OPEN_GPS) {
            if (checkGPSIsOpen()) {
                startScan();
            }
        }
    }

    //停止扫描
    private void startshowDevice() {

        if(bleDevices.size() == 0) {
            Searchble.setVisibility(View.GONE);
            devicelayout.setVisibility(View.GONE);
            chongxinble.setVisibility(View.VISIBLE);
        }else{
          updateDevice();
        }


    }

    //开始连接
    private void startConnect(final BleDevice bleDevice){

        if (!BleManager.getInstance().isConnected(bleDevice)) {
            showProgressDialog();
            BleManager.getInstance().cancelScan();
            BleUtils.setConnectListen(this);
            BleUtils.connectDev(bleDevice, Adddevice_Activity.this);


        }else{
            showToast(this, "设备已经连接");
        }


    }



    private void prepareHanddevice(BleDevice bleDevice) {
        //发送读取设备信息指令 切要添加设备到服务器，添加概用户下
        BleUtils.setBleDevice(bleDevice);
        BleUtils.setBleListen(this);
        BleUtils.setBleNotificationListen(this);
        BleUtils.setNofifyCation();

        //监听订阅成功  延时500ms在进行数据操作


    }


    @OnClick({R.id.aadddevice, R.id.cancleScan})
    public void OnClickView(View view){
        if(view.getId() == R.id.aadddevice){
            chongxinble.setVisibility(View.GONE);
            Searchble.setVisibility(View.VISIBLE);
            checkPermissions();
        }else if(view.getId() == R.id.cancleScan){
            stopScanBle();
        }
    }

    private void stopScanBle() {
        if(deviceAdapter.getItemCount() == 0) {//如果没有扫描到可以添加的设备
            Searchble.setVisibility(View.GONE);
            devicelayout.setVisibility(View.GONE);
            chongxinble.setVisibility(View.VISIBLE);
        }
    }

    private void initview() {
        title.setText("添加设备");

        Searchble = findViewById(R.id.sousuoble);
        chongxinble = findViewById(R.id.chongxinble);
        zghanwushebei = findViewById(R.id.zghanwushebei);
        Mgoadd = findViewById(R.id.goadd);
        xiansiview = findViewById(R.id.devices);
//        BACKTEM = findViewById(R.id.backerss);
//        BACKTEM.setOnClickListener(this);

        //初始化recylistview


        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        deviceAdapter = new DeviceAdapter(bleDevices);
        recyclerView.setAdapter(deviceAdapter);
        initListener();

    }

    private void updateDevice(){
        //过滤出新设备
        List<BleDevice> newbledevilist = new ArrayList<>();
        for(BleDevice bleDevice:bleDevices){
            LockInfo lockInfo = new LockInfo();
            lockInfo.setLockId(bleDevice.getMac().replace(":", ""));
            if(!userInfo.getLockInfoList().contains(lockInfo)){
                newbledevilist.add(bleDevice);
            }
        }

        if(newbledevilist.size() > 0){
            Searchble.setVisibility(View.GONE);
            devicelayout.setVisibility(View.VISIBLE);
            chongxinble.setVisibility(View.GONE);
            bleDevices = newbledevilist;
            deviceAdapter.setDeviceList(bleDevices);
            deviceAdapter.notifyDataSetChanged();
        }else{//继续扫描
//            Searchble.setVisibility(View.GONE);
//            devicelayout.setVisibility(View.GONE);
//            chongxinble.setVisibility(View.VISIBLE);
        }

    }

    private void initListener() {
        deviceAdapter.setOnItemClickListener(new OnItemClickListener(){
            @Override
            public void onItemClick(Object object, int position) {
                BleDevice bleDevice = (BleDevice) object;
                Log.e(" 点击了设置："+bleDevice.getName() ,"");
                //这里判断如果未绑定 的话需要弹框输入密码进行绑定，如果已经绑定了就进行直接连接

                //弹窗提示输入连接密码
                tipConnectPwdDialog(bleDevice);


            }
        });

    }

    private void tipConnectPwdDialog(final BleDevice bleDevice) {
        new MaterialDialog.Builder(this)
                .title("请输入连接密码")// 标题
                .inputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PERSON_NAME)// 输入类型
                .input("请输入连接密码", "", new MaterialDialog.InputCallback() {
                    @Override
                    public void onInput(@NonNull MaterialDialog dialog, CharSequence input) {
                        //Toast.makeText(FingerListActivty.this, "do something...", Toast.LENGTH_SHORT).show();

                    }
                })
                .negativeText("取消")
                .negativeColor(getResources().getColor(R.color.grey))
                .positiveText("确定")
                .onPositive(new MaterialDialog.SingleButtonCallback() {
                    @Override
                    public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                        if(TextUtils.isEmpty(dialog.getInputEditText().getText())){
                            showToast(Adddevice_Activity.this,"请输入连接密码");
                            return;
                        }
                        dialog.dismiss();
                        checkConnectpwd(bleDevice, dialog.getInputEditText().getText().toString());
                    }
                })
                .show( );// 显示对话框
    }

    //检查连接密码
    private void checkConnectpwd(final BleDevice bleDevice, String connectpwd){
        XqNetClient netClient =  new XqNetClient();
        JSONObject jsonobject = new JSONObject();

        try {
            jsonobject.put("token", userInfo.getToken());
            jsonobject.put("uid", userInfo.getUid());
            jsonobject.put("code", connectpwd);
            jsonobject.put("timestamp", TimeUtil.getSystemCurrentTimeLong()+"");
        } catch (JSONException e) {
            e.printStackTrace();
        }

        showProgressDialog();
        netClient.checkDeviceConneCode(jsonobject.toString()).enqueue(new Callback<NetResult<String>>() {//获取验证码
            @Override
            public void onResponse(Call<NetResult<String>> call, Response<NetResult<String>> response) {
                hideProgressDialog();
                Log.e("连接验证码结果是=== "+ com.alibaba.fastjson.JSONObject.toJSONString(response.body()), "");
//                com.alibaba.fastjson.JSONObject jsonObject = com.alibaba.fastjson.JSONObject.parseObject(response.body());
                if(response.body().isSuccess()){
                    //开始连接
                    showToast(Adddevice_Activity.this, "连接密码验证ok");
                    startConnect(bleDevice);
                    //设备上也需要删除指纹
                }else {
                    showToast(Adddevice_Activity.this, "连接密码验证失败:"+response.body().getMessage());
                }

            }

            @Override
            public void onFailure(Call<NetResult<String>> call, Throwable t) {
                t.printStackTrace();
                hideProgressDialog();

            }
        });
    }

    private void setScanRule() {
        String[] uuids;
        String str_uuid = null;
        if (TextUtils.isEmpty(str_uuid)) {
            uuids = null;
        } else {
            uuids = str_uuid.split(",");
        }
        UUID[] serviceUuids = null;
        if (uuids != null && uuids.length > 0) {
            serviceUuids = new UUID[uuids.length];
            for (int i = 0; i < uuids.length; i++) {
                String name = uuids[i];
                String[] components = name.split("-");
                if (components.length != 5) {
                    serviceUuids[i] = null;
                } else {
                    serviceUuids[i] = UUID.fromString(uuids[i]);
                }
            }
        }

        String[] names = new String[]{"Handle"};


        String mac = null;

        boolean isAutoConnect = false;

        BleScanRuleConfig scanRuleConfig = new BleScanRuleConfig.Builder()
                .setServiceUuids(serviceUuids)      // 只扫描指定的服务的设备，可选 new UUID[]{Stringkey.INFO_SERVICE_UUID}
                .setDeviceName(true, names)   // 只扫描指定广播名的设备，可选
                .setDeviceMac(mac)                  // 只扫描指定mac的设备，可选
                .setAutoConnect(isAutoConnect)      // 连接时的autoConnect参数，可选，默认false
                .setScanTimeOut(30000)              // 扫描超时时间，可选，默认10秒
                .build();
        BleManager.getInstance().initScanRule(scanRuleConfig);
    }

    @OnClick(R.id.BACKER)
    public void BackLastPage(){
        finish();
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        BleUtils.stopNotify();
        BleManager.getInstance().disconnectAllDevice();
        BleManager.getInstance().destroy();
    }

    @Override
    protected void onResume() {
        super.onResume();
    }



    /**
     * 无设备时
     */
    private void changesdevice() {
        Searchble.setVisibility(View.GONE);
        chongxinble.setVisibility(View.VISIBLE);
    }

    @Override
    protected void onPostResume() {
        super.onPostResume();
    }


    @Override
    public void didReciveData(byte[] data) {
        String rep = HexUtil.encodeHexStr(data);
        //分析设备基本信息
        if(rep.startsWith(Stringkey.readDeviceinfo)){
//            if(data.length == 13){
//                lockAllinfo.setSecondorder(data[12]);
//            }

            //这里需要同时时间给设备

            //
            LockInfo lockInfo = new LockInfo();
            lockInfo.setLockId(BleUtils.getBleDevice().getMac().replace(":",""));
//            if(!userInfo.getLockInfoList().contains(lockInfo))
            {//表示是第一次连接，需要添加到自己设备列表下
                lockInfo.setHardwareVersion(data[hardverindex]+ data[hardverindex+1]*256);
                lockInfo.setSoftwareVersion(data[firmwareverindex] + data[firmwareverindex+1]*256);
                lockInfo.setVendor(data[vendorindex]+ data[vendorindex+1]*256+"");
                lockInfo.setLockPower(data[volumindex]);
                lockInfo.setSerialNumber(data[serialindex]+ data[serialindex+1]*256);
                lockInfo.setLockStatus(data[lockstatusindex]);
                lockInfo.setLockName(BleUtils.getBleDevice().getName());
                addLockinfo(lockInfo);
            }

        }
    }

    //绑定设备，添加设备
    private void addLockinfo(LockInfo lockInfo){
        XqNetClient netClient =  new XqNetClient();
        JSONObject jsonobject = new JSONObject();

        try {
            jsonobject.put(Stringkey.Token, userInfo.getToken());
            jsonobject.put(Stringkey.UID, userInfo.getUid());
            jsonobject.put(Stringkey.LockId, lockInfo.getLockId());//E0:4C:63:6D:82:43
            jsonobject.put(Stringkey.LockName, lockInfo.getLockName());
            jsonobject.put(Stringkey.LockKey, lockInfo);
            jsonobject.put(Stringkey.hardwareVersion, lockInfo.getHardwareVersion());
            jsonobject.put(Stringkey.softwareVersion, lockInfo.getSoftwareVersion());
            jsonobject.put(Stringkey.Vendor, lockInfo.getVendor());
            jsonobject.put(Stringkey.serialNuber, lockInfo.getSerialNumber());
            jsonobject.put(Stringkey.lockStatus, lockInfo.getLockStatus());
            jsonobject.put(Stringkey.lockPower, lockInfo.getLockPower());
            jsonobject.put(Stringkey.Timestamp, TimeUtil.getSystemCurrentTimeLong()+"");
        } catch (JSONException e) {
            e.printStackTrace();
        }
        showProgressDialog();
        netClient.addLock(jsonobject.toString()).enqueue(new Callback<NetResult>() {//获取验证码
            @Override
            public void onResponse(Call<NetResult> call, Response<NetResult> response) {
                hideProgressDialog();
                Log.e("添加设备信息=== "+ com.alibaba.fastjson.JSONObject.toJSONString(response.body()), "");
                if(response.body().isSuccess()){
                    showToast(Adddevice_Activity.this, "添加设备成功 ");
                    Intent intent = new Intent();
                    setResult(RESULT_OK, intent);
                    finish();
                    //设备上也需要删除指纹
                }else {

                        showToast(Adddevice_Activity.this, "添加设备失败"+response.body().getMessage());
                        //当前吧设备断开
                    new Handler().postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            BleUtils.disConnectDevice();
                        }
                    }, 2000);


                }

            }

            @Override
            public void onFailure(Call<NetResult> call, Throwable t) {
                t.printStackTrace();
                hideProgressDialog();

            }
        });
    }

    @Override
    public void didConnetced(BleDevice bleDevice) {
        prepareHanddevice(bleDevice);
    }

    @Override
    public void didDisConnect(BleDevice bleDevice) {

    }

    @Override
    public void didNotification(BleDevice bleDevice, boolean result) {
        if(result){
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    BleUtils.sendData(Stringkey.readDeviceinfo);
                }
            }, 500);////监听订阅成功  延时500ms在进行数据操作
        }
    }
}
